﻿using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class HizPass : ScriptableRenderPass
{
    const string m_ProfilerTag = "Hiz Pass";

    private ComputeShader computeShader;
    private int calHizKernel;
    private RenderTargetIdentifier depthRTIdentifier;
    private int HizTexTemp = Shader.PropertyToID("_HizTexTemp");
    private RenderTexture hizTexture;

    public HizPass(RenderPassEvent evt, ComputeShader computeShader)
    {
        this.renderPassEvent = evt;
        this.computeShader = computeShader;
        this.calHizKernel = computeShader.FindKernel("CalHiz");
    }

    public bool Setup(RenderTargetIdentifier depthRTIdentifier, RenderTexture hizTexture)
    {
        this.depthRTIdentifier = depthRTIdentifier;
        this.hizTexture = hizTexture;
        return true;
    }

    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
        var cmd = CommandBufferPool.Get(m_ProfilerTag);
        int width = hizTexture.width;
        int height = hizTexture.height;

        cmd.GetTemporaryRT(HizTexTemp, width, height, 0, hizTexture.filterMode, hizTexture.format, RenderTextureReadWrite.Linear, hizTexture.antiAliasing, true);

        cmd.Blit(depthRTIdentifier, HizTexTemp);
        cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, BuiltinRenderTextureType.CameraTarget);

        cmd.CopyTexture(HizTexTemp, 0, 0, hizTexture, 0, 0);

        for (int i = 1; i < hizTexture.mipmapCount; i++)
        {
            if (i > 1)
            {
                cmd.ReleaseTemporaryRT(HizTexTemp);
                cmd.GetTemporaryRT(HizTexTemp, width, height, 0, hizTexture.filterMode, hizTexture.format, RenderTextureReadWrite.Linear, hizTexture.antiAliasing, true);
                cmd.CopyTexture(hizTexture, 0, i - 1, HizTexTemp, 0, 0);
            }
            width /= 2;
            height /= 2;
            cmd.SetComputeFloatParam(computeShader, "_uvScale", 2);
            cmd.SetComputeTextureParam(computeShader, calHizKernel, "_DepthTex", HizTexTemp);
            cmd.SetComputeTextureParam(computeShader, calHizKernel, "_HizTex", hizTexture, i);
            cmd.DispatchCompute(computeShader, calHizKernel, Mathf.CeilToInt(width / 8.0f), Mathf.CeilToInt(height / 8.0f), 1);
        }
        cmd.ReleaseTemporaryRT(HizTexTemp);
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }

}
